package com.carl.zlds.service.impl;

import com.carl.zlds.pojo.dto.AccountSearchDTO;
import com.carl.zlds.pojo.vo.*;
import com.carl.zlds.tool.common.PageBO;
import com.carl.zlds.tool.util.AssertUtil;
import com.carl.zlds.tool.util.ObjUtil;
import com.carl.zlds.tool.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carl.zlds.dao.GameAccountMapper;
import com.carl.zlds.model.GameAccount;
import com.carl.zlds.model.GameAccountDetail;
import com.carl.zlds.pojo.dto.SaveGameAccountDTO;
import com.carl.zlds.service.IGameAccountDetailService;
import com.carl.zlds.service.IGameAccountService;
import com.carl.zlds.service.IGameTagInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author carl
 */
@Slf4j
@Service
public class GameAccountServiceImpl extends ServiceImpl<GameAccountMapper, GameAccount> implements IGameAccountService {

    @Autowired
    private IGameAccountDetailService gameAccountDetailService;

    @Autowired
    private IGameTagInfoService gameTagInfoService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveGameAccount(Long id, SaveGameAccountDTO dto) {
        GameAccount gameAccount;
        if (id > 0) {
            Wrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>().eq("id", id).eq("weight", 0);
            gameAccount = this.baseMapper.selectOne(wrapper);
            AssertUtil.isNull("游戏账号不存在", gameAccount);
        } else {
            gameAccount = new GameAccount();
            gameAccount.setStatus(1);
        }

        gameAccount.setGameId(dto.getGameId());
        gameAccount.setAccount(dto.getAccount());
        gameAccount.setTitle(dto.getTitle());
        gameAccount.setPrice(dto.getPrice());
        gameAccount.setImg(dto.getImg());
        gameAccount.setLevel(dto.getLevel());
        gameAccount.setTopLevel(dto.getTopLevel());
        gameAccount.setUp(dto.getUp());
        gameAccount.setHot(dto.getHot());
        gameAccount.setS1(dto.getS1());
        gameAccount.setS2(dto.getS2());
        gameAccount.setS3(dto.getS3());
        gameAccount.setGameTagInfoList(dto.getGameTagInfoList());
        gameAccount.setLaunchTime(dto.getLaunchTime());

        if (id > 0) {
            this.baseMapper.updateById(gameAccount);
            Wrapper<GameAccountDetail> wrapper = new QueryWrapper<GameAccountDetail>().eq("game_account_id", gameAccount.getId());
            GameAccountDetail gameAccountDetail = gameAccountDetailService.getOne(wrapper);
            gameAccountDetail.setContent(dto.getContent());
            gameAccountDetailService.updateById(gameAccountDetail);
        } else {
            this.baseMapper.insert(gameAccount);
            GameAccountDetail gameAccountDetail = new GameAccountDetail();
            gameAccountDetail.setContent(dto.getContent());
            gameAccountDetail.setGameAccountId(gameAccount.getId());
            gameAccountDetailService.saveOrUpdate(gameAccountDetail);
        }
    }

    @Override
    public void deleteGameAccount(Long id) {
        Wrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>().eq("id", id).eq("weight", 0);
        GameAccount gameAccount = this.baseMapper.selectOne(wrapper);
        AssertUtil.isNull("游戏账号不存在", gameAccount);

        gameAccount.setWeight(-1);
        this.baseMapper.updateById(gameAccount);
    }

    @Override
    public Map<String, Object> getGameAccountList(Long gameId, Integer status, PageBO pageBO) {
        String limitSql = " limit " + (pageBO.getPage() - 1) * pageBO.getLimit() + ", " + pageBO.getLimit();
        List<GameAccountVO> list = this.baseMapper.getGameAccountList(gameId, status, limitSql);
        for (GameAccountVO item : list) {
            List<Long> idList = Arrays.stream(item.getGameTagInfoList().split(",")).map(StringUtil::parseLong).collect(Collectors.toList());
            List<GameTagInfoVO> tagInfoList = gameTagInfoService.getGameTagInfoListByIdList(idList);
            item.setTagInfoList(tagInfoList);
        }
        Integer count = this.baseMapper.countGameAccountList(gameId, status, "");

        Map<String, Object> map = new HashMap<>(2);
        map.put("list", list);
        map.put("count", count);

        return map;
    }

    @Override
    public Map<String, Object> getTopLevelList(Long gameId, Integer limit) {
        QueryWrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>()
                .eq("game_id", gameId)
                .eq("top_level", 1)
                .eq("status", 1)
                .eq("weight", 0);
        if (limit > 0) {
            wrapper.last("limit " + limit);
        }
        List<GameAccount> gameAccounts = this.baseMapper.selectList(wrapper);
        List<GameAccountVO> list = ObjUtil.processModelList(gameAccounts, GameAccountVO.class);

        Map<String, Object> map = new HashMap<>(1);
        map.put("list", list);

        return map;
    }

    @Override
    public Map<String, Object> getTopLevelDeal(Long gameId) {
        QueryWrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>()
                .eq("game_id", gameId)
                .eq("top_level", 1)
                .eq("status", 2)
                .eq("weight", 0);
        Integer count = this.baseMapper.selectCount(wrapper);
        String img = "";
        if (count > 0) {
            QueryWrapper<GameAccount> wrapper2 = wrapper.orderByDesc("update_time").last("limit 1");
            GameAccount gameAccount = this.baseMapper.selectOne(wrapper2);
            img = gameAccount.getImg();
        }

        Map<String, Object> map = new HashMap<>(2);
        map.put("count", count);
        map.put("img", img);
        return map;
    }

    @Override
    public Map<String, Object> statDeal(Long gameId) {
        List<GameDealStatVO> list = this.baseMapper.statDealForCurrent3Days(gameId);
        GameDealStatVO vo1 = this.baseMapper.getImgForCurrent1Day(gameId);
        GameDealStatVO vo2 = this.baseMapper.getImgForCurrent2Day(gameId);
        GameDealStatVO vo3 = this.baseMapper.getImgForCurrent3Day(gameId);
        for (GameDealStatVO item : list) {
            if (item.getDate().equals(vo1.getDate())) {
                item.setImg(vo1.getImg());
            }
            if (item.getDate().equals(vo2.getDate())) {
                item.setImg(vo2.getImg());
            }
            if (item.getDate().equals(vo3.getDate())) {
                item.setImg(vo3.getImg());
            }
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("list", list);
        return map;
    }

    @Override
    public Map<String, Object> getHomeList(Long gameId, Integer topLevel, Integer up, Integer limit) {
        QueryWrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>()
                .eq("game_id", gameId)
                .eq("status", 1)
                .eq("weight", 0);
        if (topLevel > 0) {
            wrapper.eq("top_level", 1);
        }
        if (up > 0) {
            wrapper.eq("up", 1);
        }
        if (limit > 0) {
            wrapper.last("limit " + limit);
        }
        List<GameAccount> gameAccounts = this.baseMapper.selectList(wrapper);
        List<GameAccountVO> list = ObjUtil.processModelList(gameAccounts, GameAccountVO.class);

        Map<String, Object> map = new HashMap<>(1);
        map.put("list", list);

        return map;
    }

    @Override
    public StatVO statTotalAccount(Long gameId) {
        QueryWrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>()
                .eq("status", 1)
                .eq("weight", 0);
        QueryWrapper<GameAccount> wrapper2 = new QueryWrapper<GameAccount>()
                .eq("status", 2)
                .eq("weight", 0);
        if (gameId > 0) {
            wrapper.eq("game_id", gameId);
            wrapper2.eq("game_id", gameId);
        }
        Integer accountOnSale = this.baseMapper.selectCount(wrapper);
        Integer dealOnSale = this.baseMapper.selectCount(wrapper2);
        StatVO statVO = new StatVO();
        statVO.setTotalAccountOnSale(accountOnSale);
        statVO.setTotalDealOnSale(dealOnSale);
        return statVO;
    }

    @Override
    public GameAccountVO getInfo(Long gameId, Long id) {
        GameAccountVO vo = this.baseMapper.queryGameAccountInfo(gameId, id);
        List<Long> idList = Arrays.stream(vo.getGameTagInfoList().split(",")).map(StringUtil::parseLong).collect(Collectors.toList());
        List<GameTagInfoVO> tagInfoList = gameTagInfoService.getGameTagInfoListByIdList(idList);
        List<GameTagInfoVO> list = tagInfoList.stream().filter(x -> !x.getGameTagName().equals("筛选")).collect(Collectors.toList());
        vo.setTagInfoList(list);
        return vo;
    }

    @Override
    public void soldGameAccount(Long id) {
        Wrapper<GameAccount> wrapper = new QueryWrapper<GameAccount>().eq("id", id).eq("weight", 0);
        GameAccount gameAccount = this.baseMapper.selectOne(wrapper);
        AssertUtil.isNull("游戏账号不存在", gameAccount);

        gameAccount.setStatus(2);
        this.baseMapper.updateById(gameAccount);
    }

    @Override
    public Map<String, Object> getHomeLatestList(Long gameId, Integer yesterday, Integer limit) {
        List<GameAccount> gameAccounts;
        if (yesterday > 0) {
            gameAccounts = this.baseMapper.getHomeLatest1List(gameId, limit);
        } else {
            gameAccounts = this.baseMapper.getHomeLatest7List(gameId, limit);
        }
        List<GameAccountVO> list = ObjUtil.processModelList(gameAccounts, GameAccountVO.class);

        Map<String, Object> map = new HashMap<>(1);
        map.put("list", list);

        return map;
    }

    @Override
    public Map<String, Object> accountSearch(AccountSearchDTO accountSearchDTO, PageBO pageBO) {
        String limitSql = " limit " + (pageBO.getPage() - 1) * pageBO.getLimit() + ", " + pageBO.getLimit();
        List<GameAccountVO> list = this.baseMapper.getAccountSearch(accountSearchDTO, limitSql);
        Integer count = this.baseMapper.countAccountSearch(accountSearchDTO, "");

        Map<String, Object> map = new HashMap<>(2);
        map.put("list", list);
        map.put("count", count);

        return map;
    }
}
